﻿using System;
using System.Net;
using System.Net.Sockets;
using ArivisBuildService.Properties;

namespace ArivisBuildService
{
    class Program
    {
        private static BuildServiceWorkerThread buildService;

        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Help(args);
                return;
            }

            if (args[0] == "/start")
            {
                ShowSettings();
                Start(args);
                return;
            }

            if (args[0] == "/build")
            {
                SendClientMessage("Build");
                return;
            }

            if (args[0] == "/nightly")
            {
                SendClientMessage("Nightly");
                return;
            }

            Help(args);
            return;
        }

        private static void Help(string[] args)
        {
            Console.WriteLine(Properties.Resources.Help);
            ShowSettings();
        }

        private static void ShowSettings()
        {
            Console.WriteLine("Settings:");
            Console.WriteLine(" MSBuildPath={0}", Settings.Default.MSBuildPath);
            Console.WriteLine(" NighltyTarget={0}", Settings.Default.NighltyTarget);
            Console.WriteLine(" DefaultTarget={0}", Settings.Default.DefaultTarget);
        }

        private static void Start(string[] args)
        {
            // start services
            buildService = new BuildServiceWorkerThread();
            buildService.Start();

            var tcpService = new TcpService();
            tcpService.ClientMessageRecieved += HandleClientMessage;

            // wait for exit
            while (true)
            {
                string text = Console.ReadLine();
                if (text == "quit")
                {
                    break;
                }
                Console.WriteLine("Enter 'quit'.");
            }
        }

        private static void SendClientMessage(string message)
        {
            try
            {
                using (var tcpClient = new TcpClient())
                {
                    tcpClient.Connect(IPAddress.Loopback, 1724);
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(message);
                    using (var stream = tcpClient.GetStream())
                    {
                        stream.Write(buffer, 0, buffer.Length);
                    }
                    tcpClient.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        private static void HandleClientMessage(object sender, ClientMessageEventArgs args)
        {
            int id = 0;
            string command = null;
            ParseMessage(args.Message, ref id, ref command);
            Console.WriteLine("{0}: {1}", DateTime.Now, command);
            switch (command)
            {
                case "Build":
                    buildService.Notify();
                    break;
                case "Nightly":
                    buildService.Nightly();
                    break;
                default:
                    Console.WriteLine("{0}: Unknown command {1}", System.DateTime.Now, args.Message);
                    break;
            }
        }

        private static void ParseMessage(string message, ref int id, ref string command)
        {
            if (string.IsNullOrEmpty(message))
                return;

            int index = message.IndexOf(';');
            if (index < 0)
            {
                id = 0;
                command = message;
                return;
            }

            command = message.Substring(0, index);
            int.TryParse(message.Substring(index + 1), out id);
        }
    }
}
